package com.ty.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ty.entity.AdminEntity;
import com.ty.entity.UserEntity;
import com.ty.req.UserLoginReq;
import com.ty.req.UserSaveReq;
import com.ty.req.UserUpdateReq;
import com.ty.resp.CommonResp;
import com.ty.service.IAdminService;
import com.ty.service.IUserService;
import com.ty.utils.JwtUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by IntelliJ IDEA.
 *
 * @author : txy
 * @create : 2023/12/31 11:46
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private IUserService userService;
    @Resource
    private IAdminService adminService;
    @Resource
    private JwtUtil jwtUtil = new JwtUtil();

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private JavaMailSender mailSender;

    @PostMapping("/login")
    public CommonResp login(@RequestBody UserLoginReq req) {
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        String key = "code:" + req.getCodeKey();
        CommonResp resp = new CommonResp<>();
        if (StringUtils.hasText(req.getCode()) && req.getCode().equalsIgnoreCase(ops.get(key))) {
            req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes()));
            String token = "";
            Map<String, Object> map = new HashMap<>();
            if ("admin".equals(req.getRole())) {
                AdminEntity admin = adminService.login(req);
                if (admin == null) {
                    resp.setSuccess(false);
                } else {
                    token = jwtUtil.createToken(admin);
                    admin.setPassword(null);
                    map.put("user", admin);
                }
            } else if ("user".equals(req.getRole())) {
                UserEntity user = userService.login(req);
                if (user == null) {
                    resp.setSuccess(false);
                } else {
                    token = jwtUtil.createToken(user);
                    user.setPassword(null);
                    map.put("user", user);
                }
            }
            map.put("token", token);
            System.out.println("token: " + token);
            resp.setContent(map);
        } else {
            resp.setSuccess(false);
            resp.setMessage("验证码错误");
        }
        return resp;
    }

    @PostMapping("/register")
    public CommonResp register(@RequestBody UserSaveReq req) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        String date = sdf.format(calendar.getTime());
        req.setCreateTime(date);
        //密码加密
        req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes()));
        return userService.register(req);
    }

    @GetMapping("/getUserByPhone")
    public CommonResp getUserByPhone(String phone) {
        CommonResp resp = new CommonResp<>();
        if (phone == null) {
            resp.setSuccess(false);
        } else {
            UserEntity sysUser = userService.queryByPhone(phone);
            if (sysUser == null) {
                resp.setSuccess(false);
            } else {
                resp.setContent(sysUser);
            }
        }
        return resp;
    }

    //生成code验证码
    @GetMapping("/createCode")
    public void createCode(HttpServletResponse response, String codeKey) {
        try {
            LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(100, 50, 4, 100);
            if (codeKey != null) {
                //获取验证码
                String code = lineCaptcha.getCode();
                ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
                ops.set("code:" + codeKey, code, 3, TimeUnit.MINUTES);
                response.setHeader("code", code);
                lineCaptcha.write(response.getOutputStream());
            } else {
                response.setHeader("code", "未提交时间戳");
                //lineCaptcha.write(response.getOutputStream());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @PostMapping("/updateUser")
    public CommonResp updateUser(UserEntity sysUser) {
        CommonResp resp = new CommonResp<>();
        resp.setContent(userService.updateById(sysUser));
        return resp;
    }

    @PostMapping("/updateUserPassword")
    public CommonResp updateUserPassword(UserUpdateReq sysUser) {
        sysUser.setNewPassword(DigestUtils.md5DigestAsHex(sysUser.getNewPassword().getBytes()));
        sysUser.setPassword(DigestUtils.md5DigestAsHex(sysUser.getPassword().getBytes()));
        CommonResp resp = new CommonResp<>();
        resp.setContent(userService.updatePasswordByIdAndOldPassword(sysUser));
        return resp;
    }

    @PostMapping("/updateUserPhone")
    public CommonResp updateUserPhone(UserUpdateReq sysUser) {
        CommonResp resp = new CommonResp<>();
        resp.setSuccess(userService.updatePhone(sysUser));
        if (userService.updatePhone(sysUser)) {
            resp.setMessage("修改成功");
        } else {
            resp.setMessage("输入的原始手机号码不正确");
        }
        return resp;
    }

    @GetMapping("/getUser")
    public CommonResp getUser(@RequestParam(value = "page", defaultValue = "1") Integer page,
                              @RequestParam(value = "size", defaultValue = "10") Integer size,
                              @RequestParam(value = "name", required = false) String name) {
        return userService.getUser(new Page<>(page, size), name);
    }

    //发送邮箱验证嘛
    @PostMapping("/emailCode")
    public CommonResp emailCode(String user,
                                String email,
                                String isReset) throws MessagingException {
        CommonResp resp = new CommonResp();
        //判断是否传递了账号和邮箱
        if (StringUtils.hasText(user) && StringUtils.hasText(email)) {
            QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
            UserEntity one = null;
            boolean b = StringUtils.hasText(isReset);
            if (b) {//是重置密码
                wrapper.eq("user", user);
                wrapper.eq("user_email", email);
                one = userService.getOne(wrapper);
            } else {
                wrapper.eq("user_email", email);
                one = userService.getOne(wrapper);
            }
            if ((one != null && b) || (one == null && !b)) {//是重置密码，且在数据库能找到对应账号或者不是重置密码且邮箱未被注册
                String code = CaptchaUtil.createLineCaptcha(100, 50, 4, 0).getCode();
                stringRedisTemplate.opsForValue().set("user:" + user, code + "," + email, 3, TimeUnit.MINUTES);
                MimeMessage message = mailSender.createMimeMessage();
                MimeMessageHelper messageHelper = new MimeMessageHelper(message);
                messageHelper.setTo(email);//接收人
                messageHelper.setFrom("2194145064@qq.com");//发送人
                messageHelper.setSubject("期刊订阅系统");
                messageHelper.setText("本次的验证码是：<div><h>" + code + "</h></div>" +
                        "3分钟内有效。", true);
                mailSender.send(message);
            } else {
                resp.setSuccess(false);
                resp.setMessage(b ? "邮箱与账号不对应" : "邮箱已经被注册");
            }
        } else {
            resp.setSuccess(false);
            resp.setMessage("账号或者邮箱为空");
        }
        return resp;
    }

    @PostMapping("/updateEmail")
    public CommonResp updateEmail(String user,
                                  String email,
                                  String code,
                                  String isRest) {
        CommonResp resp = new CommonResp();
        String string = stringRedisTemplate.opsForValue().get("user:" + user);
        //判断发送验证码的邮件和修改的邮件是否一致
        if (StringUtils.hasText(string) && StringUtils.hasText(email) && email.equals(string.split(",")[1]) && string.split(",")[0].equalsIgnoreCase(code)) {
            if (!StringUtils.hasText(isRest)) {//不是重置密码功能，改变原始邮件，否则不做操作，直接返回true
                QueryWrapper queryWrapper = new QueryWrapper();
                queryWrapper.eq("user_email", email);
                List list = userService.list(queryWrapper);
                if (list.isEmpty()) {//判断邮件是否被注册
                    UpdateWrapper wrapper = new UpdateWrapper();
                    wrapper.set("user_email", email);
                    wrapper.eq("user", user);
                    resp.setSuccess(userService.update(wrapper));
                } else {
                    resp.setSuccess(false);
                    resp.setMessage("邮件已经被注册，请更换");
                }
            }
        } else {
            resp.setSuccess(false);
            resp.setMessage("发送验证码的邮件和本次修改的不符");
        }
        return resp;
    }

    @PostMapping("/restPassword")
    public CommonResp restPassword(String user,
                                   String password) {
        CommonResp resp = new CommonResp();
        UpdateWrapper wrapper = new UpdateWrapper();
        wrapper.set("password", DigestUtils.md5DigestAsHex(password.getBytes()));
        wrapper.eq("user", user);
        resp.setSuccess(userService.update(wrapper));
        return resp;
    }
}
